package agents;

import jade.core.AID;
import jade.core.Agent;
import jade.core.Profile;
import jade.core.ProfileImpl;
import jade.core.Runtime;
import jade.domain.DFService;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.SearchConstraints;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.wrapper.AgentContainer;
import jade.wrapper.AgentController;
import jade.wrapper.StaleProxyException;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import building.Cell;
import building.InfoAgent;
import building.InfoGame;

/**
 * <p>
 * <B>Title:</b> Fire Evacuation
 * </p>
 * 
 * @author Carolina Arce & Caterina Bruno
 */
public class UtilsAgents {

	public static final String FIREFIGHTER_AGENT = "fireman";
	public static final String PARAMEDIC_AGENT = "paramedic";
	public static String FIREMANAGER_AGENT = "firemenmanager";
	public static String CENTRAL_AGENT = "central-agent";
	public static String FLOOR = "floor";
	public static String COORDINATOR_AGENT = "coordinator-agent";

	public static String CIVILLIAN_AGENT = "civilian";
	public static String EVACUATOR_AGENT = "evacuator";

	public static String OWNER = "urv";

	public static String LANGUAGE = "serialized-object";

	public static String ONTOLOGY = "serialized-object";

	public static String PROTOCOL_QUERY = "Query";
	public static String PROTOCOL_BLOCKED = "Block";
	public static String PROTOCOL_DOWNLOAD = "Finish_work";
	public static String PROTOCOL_MOVEMENT = "Movement";
	public static String PROTOCOL_TURN = "Turn";
	public static String GO_OUT = "Go_Out";
	public static String OK = "OK";
	public static String OUT = "OUT";
	public static String MOVE = "MOVE";
	public static String FAILURE = "failure";
	public static String CONTRACT_NET = "Contract_Net";
	public static String INFORM = "inform";

	/**
	 * Do not use it
	 */
	public UtilsAgents() {
	}

	private static long DELAY = 5000;

	/**
	 * To search an agent of a certain type
	 * 
	 * @param parent
	 *            Agent
	 * @param sd
	 *            ServiceDescription search criterion
	 * @return AID of the agent if it is foun, it is a *blocking* method //NO
	 *         ESTA FUNCIONANDO CODIGO COMENTADO
	 */
	public static AID searchAgent(Agent parent, ServiceDescription sd) {
		/** Searching an agent of the specified type **/
		AID agentBuscat = new AID();
		DFAgentDescription dfd = new DFAgentDescription();
		dfd.addServices(sd);
		try {
			while (true) {
				SearchConstraints c = new SearchConstraints();
				c.setMaxResults(new Long(-1));
				DFAgentDescription[] result = DFService.search(parent, dfd, c);
				if (result.length > 0) {

					dfd = result[0];
					agentBuscat = dfd.getName();
					System.out.println("trovato un agente" + agentBuscat);
					break;
				}
				// Thread.sleep(200); /*Each 5 seconds we try to search*/
			}
		} catch (Exception fe) {
			fe.printStackTrace();

			parent.doDelete();
		}
		return agentBuscat;
	}

	public static ArrayList<AID> searchAgentS(Agent parent,
			ServiceDescription sd) {
		/** Searching an agent of the specified type **/
		ArrayList<AID> agentFound = new ArrayList<AID>();
		DFAgentDescription dfd = new DFAgentDescription();
		dfd.addServices(sd);
		try {
			while (true) {
				SearchConstraints c = new SearchConstraints();
				c.setMaxResults(new Long(10));
				DFAgentDescription[] result = DFService.search(parent, dfd, c);
				if (result.length > 0) {
					for (int i = 0; i < result.length; i++) {
						dfd = result[i];
						agentFound.add(dfd.getName());
						System.out.println("SEARCHAGENTS trovato un agente"
								+ dfd.getName());

					}
					break;
				}
				Thread.sleep(DELAY); /* Each 5 seconds we try to search */
			}
		} catch (Exception fe) {
			fe.printStackTrace();

			parent.doDelete();
		}
		return agentFound;
	}

	// end searchAgent

	public static ArrayList<AID> searchEvacuators(Agent parent,
			ServiceDescription sd) {
		/** Searching an agent of the specified type **/
		ArrayList<AID> agentFound = new ArrayList<AID>();
		DFAgentDescription dfd = new DFAgentDescription();
		dfd.addServices(sd);
		try {
			while (true) {
				SearchConstraints c = new SearchConstraints();
				c.setMaxResults(new Long(10));
				DFAgentDescription[] result = DFService.search(parent, dfd, c);
				if (result.length > 0) {
					for (int i = 0; i < result.length; i++) {
						dfd = result[i];
						agentFound.add(dfd.getName());
						System.out.println("SEARCHAGENTS trovato un agente"
								+ dfd.getName());

					}
					break;
				}
				Thread.sleep(DELAY); /* Each 5 seconds we try to search */
			}
		} catch (Exception fe) {
			fe.printStackTrace();

			parent.doDelete();
		}
		return agentFound;
	}

	/**
	 * To create an agent in a given container
	 * 
	 * @param container
	 *            AgentContainer
	 * @param agentName
	 *            String Agent name
	 * @param className
	 *            String Agent class
	 * @param arguments
	 *            Object[] Arguments; null, if they are not needed
	 */
	public void createAgent(AgentContainer container, String agentName,
			String className, Object[] arguments) {
		try {
			AgentController controller = container.createNewAgent(agentName,
					className, arguments);
			controller.start();

		} catch (StaleProxyException e) {
			System.err.println("FATAL ERROR: " + e.toString());
		}
	} // endof createAgent

	/**
	 * To create the agent and the container together. You can specify a
	 * container and reuse it.
	 * 
	 * @param agentName
	 *            String Agent name
	 * @param className
	 *            String Class
	 * @param arguments
	 *            Object[] Arguments
	 */
	public void createAgent(String agentName, String className,
			Object[] arguments) {
		try {
			AgentContainer container = null;
			Runtime rt = Runtime.instance();
			Profile p = new ProfileImpl();
			container = rt.createAgentContainer(p);

			AgentController controller = container.createNewAgent(agentName,
					className, arguments);
			controller.start();

		} catch (Exception e) {
			System.out.println("UtilAGent Exception create agent "
					+ e.toString());
		}
	} // endof createAgent

	/**
	 * To create the agent and the container together, returning the container.
	 * 
	 * @param agentName
	 *            String Agent name
	 * @param className
	 *            String Class
	 * @param arguments
	 *            Object[] Arguments
	 * @return AgentContainer created
	 */
	public AgentContainer createAgentGetContainer(String agentName,
			String className, Object[] arguments) {
		try {
			AgentContainer container = null;
			Runtime rt = Runtime.instance();
			Profile p = new ProfileImpl();
			container = rt.createAgentContainer(p);

			AgentController controller = container.createNewAgent(agentName,
					className, arguments);
			controller.start();
			return container;

		} catch (Exception e) {
			System.out.println(e.toString());
			return null;
		}
	} // endof createAgent

	/**
	 * Finds an agent on the game map
	 * 
	 * @param agent
	 *            - the AID of the agent to search
	 * @param game
	 *            - the InfoGame
	 * @return
	 */
	public static Cell findAgent(AID agent, InfoGame game) {
		Cell agentPosition = null;
		String agentLName = agent.getLocalName();
		for (int f = 0; f < game.getMap().nfloor; f++) {
			for (int x = 0; x < game.getMap().length; x++) {
				for (int y = 0; y < game.getMap().width; y++) {
					Cell c = game.getCell(x, y, f);
					if (c != null)
						if (c.isThereAnAgent()) {
							if (c.getAgent().getAID().getLocalName()
									.equals(agentLName)) {
								agentPosition = c;
							}
						}
				}
			}
		}
		return agentPosition;
	}

	public static AID checkStairs(InfoGame game) {
		AID agentInTheStairs = null;

		for (int f = 0; f < game.getMap().nfloor; f++) {
			for (int x = 0; x < game.getMap().length; x++) {
				for (int y = 0; y < game.getMap().width; y++) {
					Cell c = game.getCell(x, y, f);
					if (c.getCellType() == Cell.STAIRS)
						if (c.isThereAnAgent()) {
							agentInTheStairs = c.getAgent().getAID();
						}
				}
			}
		}

		return agentInTheStairs;
	}

	/**
	 * Calcs the absolute distance between two cells, diagonal movement included
	 * 
	 * @param begin
	 * @param end
	 * @return distance in diagonal turns <br>
	 *         100000 if begin and/or end is null.
	 */
	public static int cellDistance(Cell begin, Cell end) {
		double c1, c2, diagonal;
		if ((begin != null) && (end != null)
				&& begin.getFloor() == end.getFloor()) {
			c1 = begin.getRow() - end.getRow();
			c2 = begin.getColumn() - end.getColumn();

			c1 = Math.pow(c1, 2);
			c2 = Math.pow(c2, 2);
			diagonal = Math.sqrt(c1 + c2);
			int distance = (int) diagonal;
			return distance;
		} else {
			return 100000;
		}

	}

	/**
	 * 
	 * @param game
	 * @return a list of all recycling centers// depues lo usaremos para el
	 *         fuego
	 */
	public static List<Cell> getRecyclingCenterList(InfoGame game) {
		List<Cell> centers = new ArrayList<Cell>();
		for (int f = 0; f < game.getMap().nfloor; f++) {
			for (int x = 0; x < game.getMap().length; x++) {
				for (int y = 0; y < game.getMap().width; y++) {
					Cell c = game.getCell(x, y, f);
					if (c != null)
						if (c.getCellType() == Cell.DOOR) {
							centers.add(c);
						}
				}
			}
		}
		return centers;
	}

	/************* CODE CATE *****************/
	/**
	 * 
	 * @param game
	 * @return a list of all injured civilian cell
	 */
	public static List<Cell> getInjuredCivilianList(InfoGame game) {
		List<Cell> centers = new ArrayList<Cell>();
		for (int f = 0; f < game.getMap().nfloor; f++) {
			for (int x = 0; x < game.getMap().length; x++) {
				for (int y = 0; y < game.getMap().width; y++) {
					Cell c = game.getCell(x, y, f);
					if (c != null)
						if (c.isThereAnAgent()) {
							InfoAgent a = c.getAgent();
							if (a.getAgentType() == InfoAgent.CIVILIAN) {
								if (a.isInjured())
									centers.add(c);
							}
						}
				}
			}
		}

		return centers;
	}

	/**
	 * 
	 * @param game
	 * @return a list of all recycling centers// depues lo usaremos para el
	 *         fuego
	 */
	public static List<Cell> getInjuredCivilianByFloor(InfoGame game, int f) {
		List<Cell> centers = new ArrayList<Cell>();
		for (int x = 0; x < game.getMap().length; x++) {
			for (int y = 0; y < game.getMap().width; y++) {
				Cell c = game.getCell(x, y, f);
				if (c != null)
					if (c.isThereAnAgent()) {
						InfoAgent a = c.getAgent();
						if (a.getAgentType() == InfoAgent.CIVILIAN) {
							if (a.isInjured())
								centers.add(c);
						}
					}
			}
		}

		return centers;
	}

	public static List<Cell> getPanicCivilianByFloor(InfoGame game, int f) {
		List<Cell> centers = new ArrayList<Cell>();
		for (int x = 0; x < game.getMap().length; x++) {
			for (int y = 0; y < game.getMap().width; y++) {
				Cell c = game.getCell(x, y, f);
				if (c != null)
					if (c.isThereAnAgent()) {
						InfoAgent a = c.getAgent();
						if (a.getAgentType() == InfoAgent.CIVILIAN) {
							if (a.getPanic() >= 80)
								centers.add(c);
						}
					}
			}
		}

		return centers;
	}

	public static Cell getNearDoor(InfoGame game, Cell myPos) {

		Cell result = null;
		int currFloor = myPos.getFloor();
		System.out.println("my pos" + myPos);

		for (int r = 0; r < game.getMap().length; r++) {
			for (int c = 0; c < game.getMap().width; c++) {

				Cell cell = game.getCell(r, c, currFloor);
				if (cell != null) {
					// System.out.println("cell is not null");
					// If that cell is building.
					if (cell.getCellType() == Cell.DOOR) {
						result = cell;
						System.out.println("ho trovato una porta" + result);
					}
				}
			}

		}
		return result;
	}

	/**
	 * 
	 * @param game
	 * @return a list of all recycling centers// depues lo usaremos para el
	 *         fuego
	 */
	public static List<Cell> getEvacuatorsByFloor(InfoGame game, int f) {
		List<Cell> centers = new ArrayList<Cell>();
		for (int x = 0; x < game.getMap().length; x++) {
			for (int y = 0; y < game.getMap().width; y++) {
				Cell c = game.getCell(x, y, f);
				if (c != null)
					if (c.isThereAnAgent()) {
						InfoAgent a = c.getAgent();
						if (a.getAgentType() == InfoAgent.EVACUATOR) {

							centers.add(c);
						}
					}
			}
		}

		return centers;
	}

	public static boolean imBlocked(InfoGame infoGame, Agent myAgent) {
		Cell myPos = agents.UtilsAgents.findAgent(myAgent.getAID(), infoGame);
		Cell up, down, right, left = null;
		int x, y, f = 0;
		int dy, dx = 0;
		x = myPos.getRow();
		y = myPos.getColumn();
		f = myPos.getFloor();
		int rows = infoGame.getNrows() - 1;

		int cols = infoGame.getMap().width - 1;
		if (y == 0 && x == 0 && f == 0) // in the superior corner first floor
		{
			try {
				System.out.println("case 1");
				if (!infoGame.getMap().getCell(x + 1, y, f).isFree()
						&& !infoGame.getMap().getCell(x, y + 1, f).isFree())
					return true;
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (x == 0 && f != 0 && (y + 1) <= cols && y >= 0) // in the superior corner, not in first
										// floor
		{
			try {
				System.out.println("case 2!!!!");
				if(infoGame.getMap().getCell(x, y, f)
								.getCellType() == Cell.DOOR){
					
					System.out.println("in a door ");
					if (!infoGame.getMap().getCell(x + 1, y, f).isFree()
						&& !infoGame.getMap().getCell(x, y + 1, f).isFree()
						&& !infoGame.getMap().getCell(x, y - 1, f).isFree()
						&& !infoGame.getMap().getCell(rows, y, f - 1).isFree()
						){
						System.out.println("blocked in door");
					return true;}
				}
				if(infoGame.getMap().getCell(x, y, f).getCellType() == Cell.DOOR 
						&& infoGame.getMap().getCell(rows, y, f - 1)
						.getCellType() != Cell.STAIRS)
					
					return true;
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (x == 0 && y == cols) // superior right corner
		{
			try {
				System.out.println("case 3");

				if (!infoGame.getMap().getCell(x + 1, y, f).isFree()
						&& !infoGame.getMap().getCell(x, y - 1, f).isFree())
					return true;

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (y == cols && x == rows) // inferior corner right
		{
			try {
				System.out.println("case 4");
				if (!infoGame.getMap().getCell(x, y - 1, f).isFree()
						&& !infoGame.getMap().getCell(x - 1, y, f).isFree())
					return true;

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (y == 0 && x == rows) // left inferior corner
		{
			try {
				System.out.println("case 5");

				if (!infoGame.getMap().getCell(x, y + 1, f).isFree()
						&& !infoGame.getMap().getCell(x - 1, y, f).isFree())
					return true;

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (x == rows && (y + 1) <= cols && y >= 0) // last row
		{
			try {
				System.out.println("case 6 stairs");
				
			
				if (!infoGame.getMap().getCell(x - 1, y, f).isFree()
						&& !infoGame.getMap().getCell(x, y + 1, f).isFree()
						&& !infoGame.getMap().getCell(x, y - 1, f).isFree())
					return true;

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (y == 0 && (x + 1) <= rows && x > 0) // first column
		{
			try {
				System.out.println("case 7");
				if (!infoGame.getMap().getCell(x + 1, y, f).isFree()
						&& !infoGame.getMap().getCell(x, y + 1, f).isFree()
						&& !infoGame.getMap().getCell(x - 1, y, f).isFree())
					return true;

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (y == cols && (x + 1) <= rows && x > 0) // last column
		{
			try {
				System.out.println("case 8");
				if (!infoGame.getMap().getCell(x + 1, y, f).isFree()
						&& !infoGame.getMap().getCell(x, y - 1, f).isFree()
						&& !infoGame.getMap().getCell(x - 1, y, f).isFree()

				)
					return true;

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		// is a valid position

		if (y + 1 >= 0 && y - 1 >= 0)
			if (y + 1 <= cols) // colonna
				if (x - 1 >= 0)
					if (x + 1 <= rows)
						try {
							System.out.println("case 9");

							if (!infoGame.getMap().getCell(x - 1, y, f)
									.isFree()
									&& !infoGame.getMap().getCell(x + 1, y, f)
											.isFree()
									&& !infoGame.getMap().getCell(x, y - 1, f)
											.isFree()
									&& !infoGame.getMap().getCell(x, y + 1, f)
											.isFree())
								return true;

						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}

		return false;
	}

	public static void changeToFire(Cell myPos, double fireIntesity) {
		// System.out.println("INzio changing to fire"+ myPos);

		if (myPos.getCellType() == Cell.STAIRS && fireIntesity >= 20)
			try {
				// System.out.println("changing to fire"+ myPos);
				myPos.setCellType(Cell.FIRE);
				if (myPos.isThereAnAgent()) {
				    myPos.getAgent().died=true;
				    myPos.getAgent().healthy=0;
					System.out.println("Agent died because of fire"
							+ myPos.getAgent().getAID());
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		if (myPos.getCellType() == Cell.DOOR && fireIntesity >= 20)
			try {
				// System.out.println("changing to fire"+ myPos);
				myPos.setCellType(Cell.FIRE);
				if (myPos.isThereAnAgent()) {
				    myPos.getAgent().died=true;
				    myPos.getAgent().healthy=0;
					System.out.println("Agent died because of fire"
							+ myPos.getAgent().getAID());
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		if (myPos.getCellType() == Cell.FREE && fireIntesity >= 20)
			try {
				// System.out.println("changing to fire"+ myPos);
				myPos.setCellType(Cell.FIRE);
				if (myPos.isThereAnAgent()) {
				    myPos.getAgent().died=true;
				    myPos.getAgent().healthy=0;
					System.out.println("Agent died because of fire"
							+ myPos.getAgent().getAID());
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		if (myPos.getCellType() == Cell.SMOKE && fireIntesity >= 20)
			try {
				// System.out.println("changing to smoke"+ myPos);
				myPos.setCellType(Cell.FIRE);
				myPos.setFireIntensityUnits(0.5);
				if (myPos.isThereAnAgent()) {
					myPos.getAgent().died=true;
				    myPos.getAgent().healthy=0;
				    
					System.out.println("Agent died because of fire"
							+ myPos.getAgent().getAID());
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		if (myPos.getCellType() == Cell.FREE && fireIntesity >= 15)
			try {

				myPos.setCellType(Cell.SMOKE);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

	}

	public static void updateSmoke(InfoGame infoGame, Cell myPos) {

		Cell up, down, right, left = null;
		int x, y, f = 0;
		int dy, dx = 0;
		x = myPos.getRow();
		y = myPos.getColumn();
		f = myPos.getFloor();
		int rows = infoGame.getNrows() - 1;
		int cols = infoGame.getMap().width - 1;
		double fireIntesity = myPos.getFireIntensityUnits();

		if (myPos.getCellType() == Cell.FIRE) {

			if (y == 0 && x == 0) // in the superior corner, not in first floor
			{
				try {
					// System.out.println("Smoke:case 1");
					changeToFire(infoGame.getMap().getCell(x + 1, y, f),
							fireIntesity);
					changeToFire(infoGame.getMap().getCell(x, y + 1, f),
							fireIntesity);

				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			if (x == 0 && y == cols) // superior right corner
			{
				try {
					// System.out.println("Smoke:case 2");

					changeToFire(infoGame.getMap().getCell(x + 1, y, f),
							fireIntesity);
					changeToFire(infoGame.getMap().getCell(x, y - 1, f),
							fireIntesity);

				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			if (y == cols && x == rows) // inferior corner right
			{
				try {

					changeToFire(infoGame.getMap().getCell(x, y - 1, f),
							fireIntesity);
					changeToFire(infoGame.getMap().getCell(x - 1, y, f),
							fireIntesity);

				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			if (y == 0 && x == rows) // left inferior corner
			{
				try {

					// System.out.println("Smoke:case 4");

					changeToFire(infoGame.getMap().getCell(x, y + 1, f),
							fireIntesity);
					changeToFire(infoGame.getMap().getCell(x - 1, y, f),
							fireIntesity);

				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (x == rows && (y + 1) <= cols && y > 0) // last row
			{
				try {

					// System.out.println("Smoke:case 5");

					changeToFire(infoGame.getMap().getCell(x - 1, y, f),
							fireIntesity);
					changeToFire(infoGame.getMap().getCell(x, y + 1, f),
							fireIntesity);
					changeToFire(infoGame.getMap().getCell(x, y - 1, f),
							fireIntesity);

				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (x == 0 && (y + 1) <= cols && y > 0) // first row
			{
				try {

					 System.out.println("Smoke:case 5b ");

					changeToFire(infoGame.getMap().getCell(x+1, y, f),
							fireIntesity);
					changeToFire(infoGame.getMap().getCell(x, y + 1, f),
							fireIntesity);
					changeToFire(infoGame.getMap().getCell(x, y - 1, f),
							fireIntesity);

				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (y == 0 && (x + 1) <= rows && x > 0) // first column
			{
				try {

					changeToFire(infoGame.getMap().getCell(x + 1, y, f),
							fireIntesity);
					changeToFire(infoGame.getMap().getCell(x, y + 1, f),
							fireIntesity);
					changeToFire(infoGame.getMap().getCell(x - 1, y, f),
							fireIntesity);

				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			if (y == cols && (x + 1) <= rows && x > 0) // last column
			{
				try {

					changeToFire(infoGame.getMap().getCell(x + 1, y, f),
							fireIntesity);
					changeToFire(infoGame.getMap().getCell(x, y - 1, f),
							fireIntesity);
					changeToFire(infoGame.getMap().getCell(x - 1, y, f),
							fireIntesity);

				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			// is a valid position

			if (y + 1 >= 0 && y - 1 >= 0)
				if (y + 1 <= cols) // colonna
					if (x - 1 >= 0)
						if (x + 1 <= rows)
							try {

								changeToFire(
										infoGame.getMap().getCell(x - 1, y, f),
										fireIntesity);
								changeToFire(
										infoGame.getMap().getCell(x + 1, y, f),
										fireIntesity);
								changeToFire(
										infoGame.getMap().getCell(x, y - 1, f),
										fireIntesity);

								changeToFire(
										infoGame.getMap().getCell(x, y + 1, f),
										fireIntesity);

							} catch (Exception e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}

		}
	}

	public Cell getFreeCell(InfoGame currentGame, int f) {
		int x = 0;
		int y = 0;

		Random rand = new Random();
		/* Ritorna il una cella libera per posizionare gli agenti */
		// System.out.println(rand + "rand");
		boolean found = true;

		while (found) {

			x = rand.nextInt(currentGame.getNcols());
			y = rand.nextInt(currentGame.getNrows());
			if (currentGame.getCell(x, y, f).getCellType() == Cell.FREE
					&& currentGame.getCell(x, y, f).isThereAnAgent() == false) {
				found = false;
				// System.out.println(x +"-"+ y );
			}
		}

		return currentGame.getCell(x, y, f);

	}

	/* Returns just neighboors Cells with agents* */
	public static List<Cell> getNeighboors(AID agent, InfoGame infoGame) {
		Cell myPos = agents.UtilsAgents.findAgent(agent, infoGame);
		Cell up, down, right, left = null;
		List<Cell> myNeighboors = new java.util.ArrayList<Cell>();
		int x, y, f = 0;
		int dy, dx = 0;
		x = myPos.getRow();
		y = myPos.getColumn();
		f = myPos.getFloor();
		int rows = infoGame.getNrows() - 1;
		int cols = infoGame.getMap().width - 1;
		if (y == 0 && x == 0 && f == 0) // in the superior corner first floor
		{
			try {
				System.out.println("neighboors:case 1");
				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));
				System.out.println(myNeighboors.size());

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (y == 0 && x == 0 && f != 0) // in the superior corner, not in first
										// floor
		{
			try {
				System.out.println("neighboors: case 2");
				/*
				 * if(!infoGame.getMap().getCell(x+1, y, f).isFree() &&
				 * !infoGame.getMap().getCell(x, y+1, f).isFree() &&
				 * !infoGame.getMap().getCell(rows, y, f-1).isFree() &&
				 * infoGame.getMap().getCell(rows, y, f-1).getCellType() ==
				 * Cell.DOOR ){
				 */
				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));
				myNeighboors.add(infoGame.getMap().getCell(rows, y, f - 1));
				myNeighboors.add(infoGame.getMap().getCell(rows, y, f - 1));
				// }
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (x == 0 && y == cols) // superior right corner
		{
			try {
				System.out.println("neighboors: case 3");

				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y - 1, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (y == cols && x == rows) // inferior corner right
		{
			try {
				System.out.println("neighboors: case 4");

				myNeighboors.add(infoGame.getMap().getCell(x, y - 1, f));
				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (y == 0 && x == rows) // left inferior corner
		{
			try {
				System.out.println("neighboors: case 5");

				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));
				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (x == rows && (y + 1) <= cols && y > 0) // last row
		{
			try {
				System.out.println("neighboors: case 6");

				myNeighboors.add(infoGame.getMap().getCell(x, y - 1, f));
				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (y == 0 && (x + 1) <= rows && x > 0) // first column
		{
			try {
				System.out.println("neighboors: case 7");

				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));
				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (y == cols && (x + 1) <= rows && x > 0) // last column
		{
			try {
				System.out.println("neighboors: case 8");

				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y - 1, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		// is a valid position

		if (y + 1 >= 0 && y - 1 >= 0)
			if (y + 1 <= cols) // colonna
				if (x - 1 >= 0)
					if (x + 1 <= rows)
						try {
							System.out.println("neighboors: case 9");

							myNeighboors.add(infoGame.getMap().getCell(x - 1,
									y, f));
							myNeighboors.add(infoGame.getMap().getCell(x + 1,
									y, f));
							myNeighboors.add(infoGame.getMap().getCell(x,
									y - 1, f));
							myNeighboors.add(infoGame.getMap().getCell(x,
									y + 1, f));

						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
		System.err.print("Neighboors of" + myPos + myNeighboors.size());
		if (myNeighboors != null)
			for (int i = 0; i < myNeighboors.size(); i++) {
				System.err.print(myNeighboors.get(i));
				if (!myNeighboors.get(i).isThereAnAgent())
					myNeighboors.remove(i);

			}
		return myNeighboors;
	}

	/* Returns free neighboors Cells with agents* */
	public static List<Cell> getFreePositons(AID agent, InfoGame infoGame) {
		Cell myPos = agents.UtilsAgents.findAgent(agent, infoGame);
		Cell up, down, right, left = null;
		List<Cell> myNeighboors = new java.util.ArrayList<Cell>();
		int x, y, f = 0;
		int dy, dx = 0;
		x = myPos.getRow();
		y = myPos.getColumn();
		f = myPos.getFloor();
		int rows = infoGame.getNrows() - 1;
		int cols = infoGame.getMap().width - 1;
		if (y == 0 && x == 0 && f == 0) // in the superior corner first floor
		{
			try {
				System.out.println("neighboors:case 1");

				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));
				System.out.println(myNeighboors.size());

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (y == 0 && x == 0 && f != 0) // in the superior corner, not in first
										// floor
		{
			try {
				System.out.println("neighboors: case 2");
				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));
				myNeighboors.add(infoGame.getMap().getCell(rows, y, f - 1));
				myNeighboors.add(infoGame.getMap().getCell(rows, y, f - 1));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (x == 0 && y == cols) // superior right corner
		{
			try {
				System.out.println("neighboors: case 3");

				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y - 1, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (y == cols && x == rows) // inferior corner right
		{
			try {
				System.out.println("neighboors: case 4");

				myNeighboors.add(infoGame.getMap().getCell(x, y - 1, f));
				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (y == 0 && x == rows) // left inferior corner
		{
			try {
				System.out.println("neighboors: case 5");

				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));
				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (x == rows && (y + 1) <= cols && y > 0) // last row
		{
			try {
				System.out.println("neighboors: case 6");

				myNeighboors.add(infoGame.getMap().getCell(x, y - 1, f));
				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (y == 0 && (x + 1) <= rows && x > 0) // first column
		{
			try {
				System.out.println("neighboors: case 7");

				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));
				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (y == cols && (x + 1) <= rows && x > 0) // last column
		{
			try {
				System.out.println("neighboors: case 8");

				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y - 1, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		// is a valid position

		if (y + 1 >= 0 && y - 1 >= 0)
			if (y + 1 <= cols) // colonna
				if (x - 1 >= 0)
					if (x + 1 <= rows)
						try {
							System.out.println("neighboors: case 9");

							myNeighboors.add(infoGame.getMap().getCell(x - 1,
									y, f));
							myNeighboors.add(infoGame.getMap().getCell(x + 1,
									y, f));
							myNeighboors.add(infoGame.getMap().getCell(x,
									y - 1, f));
							myNeighboors.add(infoGame.getMap().getCell(x,
									y + 1, f));

						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
		System.err.print("Neighboors of" + myPos + myNeighboors.size());
		if (myNeighboors != null)
			for (int i = 0; i < myNeighboors.size(); i++) {
				System.err.print(myNeighboors.get(i));
				try {
					if (!myNeighboors.get(i).isFree())
						myNeighboors.remove(i);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		return myNeighboors;
	}

	public static Cell getStairs(InfoGame game) {
		List<Cell> centers = new ArrayList<Cell>();
		for (int f = 0; f < game.getMap().nfloor; f++) {
			for (int x = 0; x < game.getMap().length; x++) {
				for (int y = 0; y < game.getMap().width; y++) {
					Cell c = game.getCell(x, y, f);
					if (c.getCellType() == Cell.STAIRS)
						return c;
				}
			}
		}
		return null;

	}

	/* Returns free neighboors Cells with agents* */
	public static List<Cell> getFreePositonsDoor(Cell myPos, InfoGame infoGame) {
		
		Cell up, down, right, left = null;
		List<Cell> myNeighboors = new java.util.ArrayList<Cell>();
		int x, y, f = 0;
		int dy, dx = 0;
		x = myPos.getRow();
		y = myPos.getColumn();
		f = myPos.getFloor();
		int rows = infoGame.getNrows() - 1;
		int cols = infoGame.getMap().width - 1;
		if (y == 0 && x == 0 && f == 0) // in the superior corner first floor
		{
			try {
				System.out.println("neighboors:case 1");

				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));
				System.out.println(myNeighboors.size());

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (y == 0 && x == 0 && f != 0) // in the superior corner, not in first
										// floor
		{
			try {
				System.out.println("neighboors: case 2");
				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));
				myNeighboors.add(infoGame.getMap().getCell(rows, y, f - 1));
				myNeighboors.add(infoGame.getMap().getCell(rows, y, f - 1));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (x == 0 && y == cols) // superior right corner
		{
			try {
				System.out.println("neighboors: case 3");

				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y - 1, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (y == cols && x == rows) // inferior corner right
		{
			try {
				System.out.println("neighboors: case 4");

				myNeighboors.add(infoGame.getMap().getCell(x, y - 1, f));
				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (y == 0 && x == rows) // left inferior corner
		{
			try {
				System.out.println("neighboors: case 5");

				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));
				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (x == rows && (y + 1) <= cols && y > 0) // last row
		{
			try {
				System.out.println("neighboors: case 6");

				myNeighboors.add(infoGame.getMap().getCell(x, y - 1, f));
				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (y == 0 && (x + 1) <= rows && x > 0) // first column
		{
			try {
				System.out.println("neighboors: case 7");

				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y + 1, f));
				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (y == cols && (x + 1) <= rows && x > 0) // last column
		{
			try {
				System.out.println("neighboors: case 8");

				myNeighboors.add(infoGame.getMap().getCell(x - 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x + 1, y, f));
				myNeighboors.add(infoGame.getMap().getCell(x, y - 1, f));

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		// is a valid position

		if (y + 1 >= 0 && y - 1 >= 0)
			if (y + 1 <= cols) // colonna
				if (x - 1 >= 0)
					if (x + 1 <= rows)
						try {
							System.out.println("neighboors: case 9");

							myNeighboors.add(infoGame.getMap().getCell(x - 1,
									y, f));
							myNeighboors.add(infoGame.getMap().getCell(x + 1,
									y, f));
							myNeighboors.add(infoGame.getMap().getCell(x,
									y - 1, f));
							myNeighboors.add(infoGame.getMap().getCell(x,
									y + 1, f));

						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
		System.err.print("Neighboors of" + myPos + myNeighboors.size());
		if (myNeighboors != null)
			for (int i = 0; i < myNeighboors.size(); i++) {
				System.err.print(myNeighboors.get(i));
				try {
					if (!myNeighboors.get(i).isFree())
						myNeighboors.remove(i);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		return myNeighboors;
	}
} // endof UtilsAgents
